import { ClientMessage } from "@runtime/generate/message/ClientMessage";
import WebSocketComponent from "@runtime/module/WebSocket/WebSocketComponent";

/**
 * GameObject组件
 */
export default class GameObjectComponent {
    private static instance: GameObjectComponent = new GameObjectComponent();
    /**
     * GameObject组件
     */
    public static get Default(): GameObjectComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);
    }

    /**
     * 根据路径查找物体
     * @param path 路径
     * @param instanceId 父物体实例Id(UnityGameObject), 0 为全局查找
     * @returns 物体的实例Id
     */
    public async FindAsync(path: string, instanceId: number = 0): Promise<number> {
        const response: ClientMessage.FindGameObjectResponse = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.FindGameObjectRequest(path, instanceId));
        return response.InstanceId;
    }

    /**
     * 显示物体
     * @param input 物体实例Id
     * @returns 操作结果
     */
    public async ShowAsync(input: number | Array<number>): Promise<boolean> {
        const request = new ClientMessage.ShowGameObjectRequest(typeof input == 'number' ? [input] : input);
        const response = await WebSocketComponent.Default.PostMessageAsync(request);
        return response.Error == 0;
    }

    /**
     * 隐藏物体
     * @param input 物体实例Id
     * @returns 操作结果
     */
    public async HideAsync(input: number | Array<number>): Promise<boolean> {
        const request = new ClientMessage.HideGameObjectRequest(typeof input == 'number' ? [input] : input);
        const response = await WebSocketComponent.Default.PostMessageAsync(request);
        return response.Error == 0;
    }

    /**
     * 销毁物体
     * @param input 物体实例Id
     * @returns 操作结果
     */
    public async DestroyAsync(input: number | Array<number>, immediately: boolean = false): Promise<boolean> {
        const request = new ClientMessage.DestroyGameObjectRequest(typeof input == 'number' ? [input] : input, immediately);
        const response = await WebSocketComponent.Default.PostMessageAsync(request);
        return response.Error == 0;
    }

    /**
     * 获取物体坐标
     * @param instanceId 物体实例Id
     * @param space 空间 0:World 1: Self
     * @returns 物体坐标
     */
    public async GetPositionAsync(instanceId: number, space: number = 0): Promise<Array<number>> {
        const response: ClientMessage.GetGameObjectPositionResponse = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.GetGameObjectPositionRequest(instanceId, space));
        return response.Position;
    }

    /**
     * 设置物体坐标
     * @param instanceId 物体实例Id
     * @param position 坐标
     * @param space 空间 0:World 1: Self
     * @returns 操作结果
     */
    public async SetPositionAsync(instanceId: number, position: Array<number>, space: number = 0): Promise<boolean> {
        const response: ClientMessage.SetGameObjectPositionResponse = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.SetGameObjectPositionRequest(instanceId, position, space));
        return response.Error == 0;
    }

    /**
     * 获取物体欧拉角
     * @param instanceId 物体实例Id
     * @param space 空间 0:World 1: Self
     * @returns 物体欧拉角
     */
    public async GetEulerAnglesAsync(instanceId: number, space: number = 0): Promise<Array<number>> {
        const response: ClientMessage.GetGameObjectEulerAnglesResponse = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.GetGameObjectEulerAnglesRequest(instanceId, space));
        return response.EulerAngles;
    }

    /**
     * 设置物体欧拉角
     * @param instanceId 物体实例Id
     * @param eulerAngles 欧拉角
     * @param space 空间 0:World 1: Self
     * @returns 操作结果
     */
    public async SetEulerAnglesAsync(instanceId: number, eulerAngles: Array<number>, space: number = 0): Promise<boolean> {
        const response: ClientMessage.SetGameObjectEulerAnglesResponse = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.SetGameObjectEulerAnglesRequest(instanceId, eulerAngles, space));
        return response.Error == 0;
    }

    /**
     * 获取物体名称
     * @param instanceId 物体实例Id
     * @returns 物体坐标
     */
    public async GetNameAsync(instanceId: number): Promise<string> {
        const response: ClientMessage.GetGameObjectNameResponse = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.GetGameObjectNameRequest(instanceId));
        return response.Name;
    }

    /**
     * 设置物体名称
     * @param instanceId 物体实例Id
     * @param name 名称
     * @returns 操作结果
     */
    public async SetNameAsync(instanceId: number, name: string): Promise<boolean> {
        const response: ClientMessage.SetGameObjectNameResponse = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.SetGameObjectNameRequest(instanceId, name));
        return response.Error == 0;
    }

    /**
     * 设置父节点
     * @param parent 父节点
     * @param worldPositionStays 保持世界坐标
     */
    public async SetParentAsync(gameObject: number, parent: number, worldPositionStays: boolean = true): Promise<boolean> {
        const response: ClientMessage.SetGameObjectParentResponse = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.SetGameObjectParentRequest(gameObject, parent, worldPositionStays));
        return response.Error == 0;
    }
}